package com.amir.common.mvp.model;

import android.annotation.SuppressLint;
import android.text.TextUtils;

import com.amir.common.api.HttpManager;
import com.amir.common.mvp.IModel;
import com.amir.common.utils.MathUtils;
import com.amir.common.api.ApiServer;
import com.amir.common.api.CustomObserver;

import com.amir.common.api.upload.FileUploadObserver;

import com.google.gson.Gson;

import org.json.JSONObject;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;


public class Model implements IModel {


    @SuppressLint("CheckResult")
    public static <B> Observable getObservable(Observable<B> observable, CustomObserver<B> customObserver) {

        observable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(customObserver);

        return observable;
    }


    @SuppressLint("CheckResult")
    public static  Observable getObservableFile(Observable<ResponseBody> observable, FileUploadObserver<ResponseBody> customObserver) {

        observable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(customObserver);

        return observable;
    }




    public static ApiServer getServer() {
        return HttpManager.getRequest(ApiServer.class);
    }

    public static ApiServer getServerPay() {
        return HttpManager.getRequest(ApiServer.class);
    }


    public static RequestBody getRequestBody(Map<String, Object> map) {
        JSONObject jsonObject = new JSONObject(map);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),
                String.valueOf(jsonObject));

        return requestBody;
    }

    public static RequestBody getRequestBody(LinkedHashMap<String, String> map) {
        JSONObject jsonObject = new JSONObject(map);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),
                String.valueOf(jsonObject));

        return requestBody;
    }



    /**
     * 字符串按照 ASCII 表升序
     * @param
     * @return
     */
    private static String  ASCIISort(TreeMap<String, Object> map) {
        List<Map.Entry<String, Object>> infos = new ArrayList<>(map.entrySet());

//        Collections.sort(infos, (o1, o2) -> (o1.getKey()).compareTo(o2.getKey()));
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, Object> item : infos) {

            if (sb.length() == 0) {
                sb.append(item.getKey() + "=" + item.getValue());
            }else {
                sb.append("&"+item.getKey() + "=" + item.getValue());
            }


        }
        System.out.println("排序后："+sb.toString());
        return sb.toString();
    }



    /**
     * sha1加密
     * @param data
     * @return
     * @throws NoSuchAlgorithmException
     */
    private static String sha1(String data)  {
        //加盐   更安全一些
//        data += "lyz";
        //信息摘要器                                算法名称
        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("SHA1");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        //把字符串转为字节数组
        byte[] b = data.getBytes();
        //使用指定的字节来更新我们的摘要
        md.update(b);
        //获取密文  （完成摘要计算）
        byte[] b2 = md.digest();
        //获取计算的长度
        int len = b2.length;
        //16进制字符串
        String str = "0123456789abcdef";
        //把字符串转为字符串数组
        char[] ch = str.toCharArray();

        //创建一个40位长度的字节数组
        char[] chs = new char[len*2];
        //循环20次
        for(int i=0,k=0;i<len;i++) {
            byte b3 = b2[i];//获取摘要计算后的字节数组中的每个字节
            // >>>:无符号右移
            // &:按位与
            //0xf:0-15的数字
            chs[k++] = ch[b3 >>> 4 & 0xf];
            chs[k++] = ch[b3 & 0xf];
        }

        //字符数组转为字符串
        return new String(chs);
    }
    /**
     * 对字符串进行32位MD5加密
     * @param str
     * @return
     */
    private static String EncodeByMD5(String str) {
        byte[] hash;
        try {
            hash = MessageDigest.getInstance("MD5").digest(str.getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("NoSuchAlgorithmException",e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("UnsupportedEncodingException", e);
        }
        //对生成的16字节数组进行补零操作
        StringBuilder hex = new StringBuilder(hash.length * 2);//32位
//        StringBuilder hex = new StringBuilder(hash.length);
        for (byte b : hash) {
            if ((b & 0xFF) < 0x10){
                hex.append("0");
            }
            hex.append(Integer.toHexString(b & 0xFF));
        }
//        return hex.toString().toUpperCase();
        return hex.toString();
    }
    /**
     * 对文本进行MD5加密
     * @param plainText 要进行加密的文本
     *  @param param 指定获取16位/32位加密数据
     * @return 加密后的内容
     */
    public static String textToMD5L32(String plainText,Integer param){
        String result = null;
        //首先判断是否为空
        if(TextUtils.isEmpty(plainText)){
            return null;
        }
        try{
            //首先进行实例化和初始化
            MessageDigest md = MessageDigest.getInstance("MD5");
            //得到一个操作系统默认的字节编码格式的字节数组
            byte[] btInput = plainText.getBytes();
            //对得到的字节数组进行处理
            md.update(btInput);
            //进行哈希计算并返回结果
            byte[] btResult = md.digest();
            //进行哈希计算后得到的数据的长度
            StringBuffer sb = new StringBuffer();
            for(byte b : btResult){
                int bt = b&0xff;
                if(bt<16){
                    sb.append(0);
                }
                sb.append(Integer.toHexString(bt));
            }

            if(param == 16){
                result=	sb.toString().substring(8, 24);
            }else if(param == 32){
                result = sb.toString();
            }
            return result;
        }catch(NoSuchAlgorithmException e){
            e.printStackTrace();
        }
        return result;
    }



    public static TreeMap<String, Object> sign(TreeMap<String, Object> map){
        return getToken(map);
    }
   private static TreeMap<String, Object> getToken(TreeMap<String, Object> map){

       String s = MathUtils.makeUpNewData(Thread.currentThread().hashCode() + "", 3);
       String s1 = MathUtils.randomDigitNumber(7);
//       System.out.println(s+s1);
       map.put("token",s+s1);
       String mapstr = new Gson().toJson(map);

       System.out.println(mapstr);
       String sha1 = sha1(ASCIISort(map));
       System.out.println("SHA1拼接前:"+sha1);
       sha1 += "#l_vle_ll_e%+$^@0608)[";
       String md5 = EncodeByMD5(sha1);
       System.out.println("SHA1拼接后:"+sha1);
       System.out.println("MD5:"+md5);
       map.put("signature",md5);
       return map;
    }


//
//    public static void main(String[] str){
//        TreeMap<String, Object> map = getMap();
////        map.put(Contens.EMAIL,"2447971613@qq.com");
//        map.put("phone","18637051978");
////        map.put("type",1);
//        String s = new Gson().toJson(sign(map));
//        System.out.println(s);
////        String sha1 = sha1("sfksjfksjksdsadasdas");
////        System.out.println(sha1);
////        getToken(map);
//    }
}
